package Submarine;

import javax.swing.JFrame;
import javax.swing.JPanel;//1. 第一步
import java.awt.*;
import java.util.Random;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

/**
 * 游戏窗口 宽和高为常量，适当地方做修改641w 479h
 */

/**
 * swing相关的 ------ 专门做窗口
 * 几乎已经被淘汰了，应用率叽叽叽叽低
 * <p>
 * 画窗口： ------ 在World类中共3步
 */
public class World extends JPanel {//2. 第二步
    public static final int WIDTH = 641;
    public static final int HEIGHT = 479;

    public static final int RUNNING = 0;
    public static final int GAME_OVER = 1;
    public static final int PAUSE = 2;
    public int state = RUNNING;

    //准备对象
    private Battleship bs = new Battleship();//战舰对象
    //潜艇(侦察潜艇、鱼雷潜艇、水雷其他)数组
    private SeaObject[] sb = {};
    //水雷数组
    private Mine[] mines = {};
    //炸弹数组
    private Bomb[] bombs = {};
    //超级水雷
    private SuperMine[] smines = {};
    //死神镰刀
    private DevilAttack[] DA = {};
    //空中支援飞机
    private AirSupportPlane[] asp = {};
    //诱导弹
    private Amor[] am = {};
    //空投支援箱
    private airbox[] ai = {};
    //诱导弹支援箱
    private airbox1[] ai1 = {};
    //无敌支援箱
    private airbox2[] ai2 = {};

    /**
     * 生成死神镰刀
     */
    private int EnterDevilAttackIndex = 0;

    public void EnterDevilAttack() {
        EnterDevilAttackIndex++;
        if (EnterDevilAttackIndex % (int) (100 / (x+times-1)) == 0) {
            for (int i = 0; i < sb.length; i++) {
                if (this.sb[i] instanceof Devil) {
                    Devil d = (Devil) sb[i];
                    DevilAttack ojbk = d.shootDevailAttack();
                    DA = Arrays.copyOf(DA, DA.length + 1);
                    DA[DA.length - 1] = ojbk;
                }
            }
        }
    }

    /**
     * 生成超级水雷
     */
    private int EnterSuperMineIndex = 0;

    public void EnterSuperMine() {
        EnterSuperMineIndex++;
        if (EnterSuperMineIndex % (int) (100 / (x+times-1)) == 0) {
            for (int i = 0; i < sb.length; i++) {
                if (this.sb[i] instanceof JinSubmarine) {
                    JinSubmarine j = (JinSubmarine) sb[i];
                    SuperMine ojbk1 = j.shootSuperMine();
                    SuperMine ojbk11 = j.shootSuperMine1();
                    SuperMine ojbk12 = j.shootSuperMine2();
                    smines = Arrays.copyOf(smines, smines.length + 3);
                    smines[smines.length - 1] = ojbk1;
                    smines[smines.length - 2] = ojbk11;
                    smines[smines.length - 3] = ojbk12;
                }
            }
        }
    }

    /**
     * 水雷生成速率
     */
    private int EnterMineIndaex = 0;

    public void EnterMine() {
        EnterMineIndaex++;
        if (EnterMineIndaex % (int) (80 / (times+x-1)) == 0) {
            for (int i = 0; i < sb.length; i++) {
                if (this.sb[i] instanceof MineSubmarine) {
                    MineSubmarine ms = (MineSubmarine) sb[i];
                    Mine ojbk = ms.shootMine();
                    mines = Arrays.copyOf(mines, mines.length + 1);
                    mines[mines.length - 1] = ojbk;
                }
            }
        }
    }

    /**
     * 随机生成潜艇
     */
    public SeaObject nextSubmarine() {
        Random rand = new Random();
        int num = rand.nextInt(40);
        if (num < (int) (15 - times)) {
            return new ObserveSubmarine();
        } else if (num < (int) (25 - times)) {
            return new TorpedoSubmarine();
        } else if (num < (int) (34 - times)) {
            return new MineSubmarine();
        } else if (num < (int) (38 - times)) {
            return new JinSubmarine();
        } else {
            return new Devil();
        }
    }

    /**
     * 潜艇生成速率
     */
    private int EnterSeaObjectIndex = 0;

    public void EnterSeaObject() {
        EnterSeaObjectIndex++;
        if (EnterSeaObjectIndex % (36 - x) == 0) {
            SeaObject obj = nextSubmarine();
            sb = Arrays.copyOf(sb, sb.length + 1);
            sb[sb.length - 1] = obj;
        }
    }

    /**
     * 海洋对象动起来
     */
    public void moveAction() {
        for (int i = 0; i < sb.length; i++) {
            sb[i].move();
        }
        for (int i = 0; i < mines.length; i++) {
            mines[i].move();
        }
        for (int i = 0; i < bombs.length; i++) {
            bombs[i].move();
        }
        for (int i = 0; i < smines.length; i++) {
            smines[i].move();
        }
        for (int i = 0; i < DA.length; i++) {
            DA[i].move();
        }
        //诱导弹
        for (int i = 0; i < am.length; i++) {
            am[i].move();
        }
        //支援机动起来
        for (int i = 0; i < asp.length; i++) {
            asp[i].move();
        }
        //空投支援箱
        for (int i = 0; i < ai.length; i++) {
            ai[i].move();
        }
        //诱导弹箱
        for (int i = 0; i < ai1.length; i++) {
            ai1[i].move();
        }
        //诱导弹箱
        for (int i = 0; i < ai2.length; i++) {
            ai2[i].move();
        }
    }

    /**
     * 世界成长
     */
    public static double times = 1.000;

    public void increTimes() {
        if (score >= 1000) {
            times = score / 1000;
        }
    }

    /**
     * 诱导弹生成
     */
    private int EnterAmorIndex = 0;

    public void EnterAmor() {
        EnterAmorIndex++;
        if (EnterAmorIndex % 5 == 0) {
            for (int i = 0; i < asp.length; i++) {
                Amor amor = asp[i].shootamor();
                am = Arrays.copyOf(am, am.length + 1);
                am[am.length - 1] = amor;
            }
        }
    }

    /**
     * 飞机生成
     */
    private int usage = 0;//使用次数(还没调用)

    public void EnterPlane() {
        SeaObject ojbk = new AirSupportPlane();
        asp = Arrays.copyOf(asp, asp.length + 1);
        asp[asp.length - 1] = (AirSupportPlane) ojbk;
    }

    /**
     * 支援箱生成
     */
    private int EnterAirBoxIndex = 0;

    private void EnterAirBox() {
        EnterAirBoxIndex++;
        if (EnterAirBoxIndex % 2000 == 0) {
            Random rand = new Random();
            int num = rand.nextInt(610);
            airbox a = new airbox(num);
            ai = Arrays.copyOf(ai, ai.length + 1);
            ai[ai.length - 1] = a;
        }
    }

    /**
     * 静止箱生成
     */
    private int EnterAirBoxIndex1 = 0;

    private void EnterAirBox1() {
        EnterAirBoxIndex1++;
        if (EnterAirBoxIndex1 % 800 == 0) {
            Random rand = new Random();
            int num = rand.nextInt(610);
            airbox1 a = new airbox1(num);
            ai1 = Arrays.copyOf(ai1, ai1.length + 1);
            ai1[ai1.length - 1] = a;
        }
    }

    /**
     * 无敌箱生成
     */
    private int EnterAirBoxIndex2 = 0;

    private void EnterAirBox2() {
        EnterAirBoxIndex2++;
        if (EnterAirBoxIndex2 % 1300 == 0) {
            Random rand = new Random();
            int num = rand.nextInt(610);
            airbox2 a = new airbox2(num);
            ai2 = Arrays.copyOf(ai2, ai2.length + 1);
            ai2[ai2.length - 1] = a;
        }
    }

    /**
     * 无敌转换
     */
    public static final int NORMAL = 0;
    public static final int INVICIBLE = 1;
    private int invicibleIndex = 0;

    private void changeState() {
        invicibleIndex++;
        if (bs.bsstate == INVICIBLE && invicibleIndex % 700 == 0) {
            bs.bsstate = NORMAL;
        }
    }

    /**
     * 消除无敌执行
     */
    private void fadeinvicible() {
        if (bs.bsstate == NORMAL) {
            MineSeaObjectBattleshipCrash();
        }
        for (int i = 0; i < ai.length; i++) {
            airbox a = ai[i];
            if (a.isLive() && bs.isLive() && a.isHit(bs)) {
                a.goDead();
                usage++;
            }//道具死亡和战舰减命
        }
        for (int i = 0; i < ai1.length; i++) {
            airbox1 a = ai1[i];
            if (a.isLive() && bs.isLive() && a.isHit(bs)) {
                a.goDead();
                clearbomb++;
            }//道具死亡和战舰减命
        }
        for (int i = 0; i < ai2.length; i++) {
            airbox2 a = ai2[i];
            if (a.isLive() && bs.isLive() && a.isHit(bs)) {
                a.goDead();
                bs.bsstate = INVICIBLE;
            }//道具死亡和战舰减命
        }
    }

    /**
     * 启动程序的执行
     */
    public void Action() {
        KeyAdapter k = new KeyAdapter() {
            /** 重写keyReleased()案件抬起事件 */
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_P) {
                    if (state == RUNNING) {
                        state = PAUSE;
                    } else if (state == PAUSE) {
                        state = RUNNING;
                    }
                }
                if (e.getKeyCode() == KeyEvent.VK_S && usage > 0) {
                    EnterPlane();//飞机进场
                    usage--;
                }
                if (e.getKeyCode() == KeyEvent.VK_A && clearbomb > 0) {
                    stop();//飞机进场
                    clearbomb--;
                }
                switch (e.getKeyCode()) {
                    case KeyEvent.VK_SPACE:
                        Bomb obj = bs.shootBomb();
                        bombs = Arrays.copyOf(bombs, bombs.length + 1);
                        bombs[bombs.length - 1] = obj;
                        break;
                    case KeyEvent.VK_LEFT:
                        bs.moveL();
                        break;
                    case KeyEvent.VK_RIGHT:
                        bs.moveR();
                        break;
                }
            }
        };//键盘侦听器
        this.addKeyListener(k);//增添侦听器

        Timer timer = new Timer();
        int interval = 10;
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (state == RUNNING) {
                    AirBoxSeaObjectCrash();//空投箱和潜艇碰撞
                    EnterSeaObject();//海洋对象进场
                    EnterMine();//水雷进场
                    EnterDevilAttack();//死神镰刀进场
                    EnterSuperMine();//超级水雷进场
                    EnterAmor();// 支援弹进场
                    AmorBattleshipCrash();//诱导弹碰撞检测
                    moveAction();//海洋对象全员动起来
                    BombBattleshipCrash();//炸弹碰撞检测
                    fadeinvicible();//俩状态战舰碰撞检测
                    fadeSeaObject();//消除海洋对象
                    gameover();
                    changeState();
                    EnterAirBox();//空投箱进场
                    EnterAirBox1();//支援箱进场
                    EnterAirBox2();//无敌箱进场
                    increTimes();//世界成长
                    repaint();
                }
            }
        }, interval, interval);
    }

    /**
     * 炸弹海底单位碰撞检测
     */
    private int score = 0;

    //炸弹碰撞
    private void BombBattleshipCrash() {
        for (int i = 0; i < bombs.length; i++) {//遍历炸弹数组
            Bomb b = bombs[i];
            for (int j = 0; j < sb.length; j++) {//遍历海底单位数组
                SeaObject s = sb[j];
                if (s instanceof Devil) {//死神碰撞检测
                    Devil d = (Devil) s;
                    if (b.isLive() && d.isLive() && b.isHit(s)) {//炸弹死神碰撞判断
                        b.goDead();
                        d.loselife();
                        if (d.life() <= 0) {//检测死神生命值
                            d.goDead();
                            if (d instanceof EnemyScore) {
                                EnemyScore es = (EnemyScore) d;
                                score += es.getScore();
                            }
                            if (d instanceof EnemyLife) {
                                EnemyLife el = (EnemyLife) d;
                                int num = el.getLife();
                                bs.addLife(num);
                            }
                        }
                    }
                } else {//别的海底单位
                    if (b.isLive() && s.isLive() && b.isHit(s)) {
                        s.goDead();
                        b.goDead();
                        if (s instanceof EnemyScore) {
                            EnemyScore es = (EnemyScore) s;
                            score += es.getScore();
                        }
                        if (s instanceof EnemyLife) {
                            EnemyLife el = (EnemyLife) s;
                            int num = el.getLife();
                            bs.addLife(num);
                        }
                    }
                }
            }
        }
    }

    //支援弹碰撞
    private void AmorBattleshipCrash() {
        for (int i = 0; i < am.length; i++) {//遍历炸弹数组
            Amor a = am[i];
            for (int j = 0; j < sb.length; j++) {//遍历海底单位数组
                SeaObject s = sb[j];
                if (a.isLive() && s.isLive() && a.isHit(s)) {
                    s.goDead();
                    a.goDead();
                    if (s instanceof EnemyScore) {
                        EnemyScore es = (EnemyScore) s;
                        score += es.getScore();
                    }
                    if (s instanceof EnemyLife) {
                        EnemyLife el = (EnemyLife) s;
                        int num = el.getLife();
                        bs.addLife(num);
                    }
                }
            }
        }
    }

    /**
     * 战舰和道具碰撞检测
     */
    private void MineSeaObjectBattleshipCrash() {
        for (int i = 0; i < mines.length; i++) {
            Mine m = mines[i];
            if (m.isLive() && bs.isLive() && m.isHit(bs)) {
                m.goDead();
                EnemyLife el = (EnemyLife) m;
                int num = el.getLife();
                bs.decreLife(num);
            }//道具死亡和战舰减命
        }
        for (int i = 0; i < smines.length; i++) {
            SuperMine sm = smines[i];
            if (sm.isLive() && bs.isLive() && sm.isHit(bs)) {
                sm.goDead();
                EnemyLife el = (EnemyLife) sm;
                int num = el.getLife();
                bs.decreLife(num);
            }//道具死亡和战舰减命
        }
        for (int i = 0; i < DA.length; i++) {
            DevilAttack da = DA[i];
            if (da.isLive() && bs.isLive() && da.isHit(bs)) {
                da.goDead();
                EnemyLife el = (EnemyLife) da;
                int num = el.getLife();
                bs.decreLife(num);
            }//道具死亡和战舰减命
        }
    }

    /**
     * 空投箱与潜艇碰撞检测
     */
    private void AirBoxSeaObjectCrash() {
        for (int i = 0; i < ai.length; i++) {//遍历炸弹数组
            airbox a = ai[i];
            for (int j = 0; j < sb.length; j++) {//遍历海底单位数组
                SeaObject s = sb[j];
                if (a.isLive() && s.isLive() && a.isHit(s)) {
                    a.goDead();
                    UpBuff();
                }
            }
        }
        for (int i = 0; i < ai1.length; i++) {//遍历炸弹数组
            airbox1 a = ai1[i];
            for (int j = 0; j < sb.length; j++) {//遍历海底单位数组
                SeaObject s = sb[j];
                if (a.isLive() && s.isLive() && a.isHit(s)) {
                    a.goDead();
                    UpBuff();
                }
            }
        }
        for (int i = 0; i < ai2.length; i++) {//遍历炸弹数组
            airbox2 a = ai2[i];
            for (int j = 0; j < sb.length; j++) {//遍历海底单位数组
                SeaObject s = sb[j];
                if (a.isLive() && s.isLive() && a.isHit(s)) {
                    a.goDead();
                    UpBuff();
                }
            }
        }
    }

    /**
     * 潜艇增益
     */
    private int UpBuffIndex = 0;
    private int x =1;

    private void UpBuff() {
        UpBuffIndex++;
        if(UpBuffIndex%500==0) {
            x = 2;
        }
        x = 1;
        }

    /**
     * 对象静止
     */
    private  int time = 1;
    private int clearbomb = 0;

    private void stop() {
        for (int i = 0; i < sb.length; i++) {
            sb[i].speed = 0;
        }
    }

    /**
     * 消除海洋元素
     */
    private void fadeSeaObject() {
        // 消潜艇
        for (int i = 0; i < sb.length; i++) {
            if (sb[i].isOutofBounds() || sb[i].isDead()) {
                sb[i] = sb[sb.length - 1];
                sb = Arrays.copyOf(sb, sb.length - 1);
            }
        }
        // 消水雷
        for (int i = 0; i < mines.length; i++) {
            if (mines[i].isOutofBounds() || mines[i].isDead()) {
                mines[i] = mines[mines.length - 1];
                mines = Arrays.copyOf(mines, mines.length - 1);
            }
        }
        // 消炸弹
        for (int i = 0; i < bombs.length; i++) {
            if (bombs[i].isOutofBounds() || bombs[i].isDead()) {
                bombs[i] = bombs[bombs.length - 1];
                bombs = Arrays.copyOf(bombs, bombs.length - 1);
            }
        }
        // 消镰刀
        for (int i = 0; i < DA.length; i++) {
            if (DA[i].isOutofBounds() || DA[i].isDead()) {
                DA[i] = DA[DA.length - 1];
                DA = Arrays.copyOf(DA, DA.length - 1);
            }
        }
        // 消超级水雷
        for (int i = 0; i < smines.length; i++) {
            if (smines[i].isOutofBounds() || smines[i].isDead()) {
                smines[i] = smines[smines.length - 1];
                smines = Arrays.copyOf(smines, smines.length - 1);
            }
        }
        // 消除飞机
        for (int i = 0; i < asp.length; i++) {
            if (asp[i].isOutofBounds()) {
                asp[i] = asp[asp.length - 1];
                asp = Arrays.copyOf(asp, asp.length - 1);
            }
        }
        // 消诱导弹
        for (int i = 0; i < am.length; i++) {
            if (am[i].isOutofBounds() || am[i].isDead()) {
                am[i] = am[am.length - 1];
                am = Arrays.copyOf(am, am.length - 1);
            }
        }// 消支援箱
        for (int i = 0; i < ai.length; i++) {
            if (ai[i].isOutofBounds() || ai[i].isDead()) {
                ai[i] = ai[ai.length - 1];
                ai = Arrays.copyOf(ai, ai.length - 1);
            }
        }// 消诱导箱
        for (int i = 0; i < ai1.length; i++) {
            if (ai1[i].isOutofBounds() || ai1[i].isDead()) {
                ai1[i] = ai1[ai1.length - 1];
                ai1 = Arrays.copyOf(ai1, ai1.length - 1);
            }
        }// 消无敌箱
        for (int i = 0; i < ai2.length; i++) {
            if (ai2[i].isOutofBounds() || ai2[i].isDead()) {
                ai2[i] = ai2[ai2.length - 1];
                ai2 = Arrays.copyOf(ai2, ai2.length - 1);
            }
        }
    }

    /**
     * 检测游戏结束
     */
    private boolean gameovercheck() {
        return bs.life <= 0;
    }

    /**
     * 游戏结束
     */
    private void gameover() {
        if (gameovercheck()) {
            state = GAME_OVER;
        } else if (score >= 5000) {
            state = GAME_OVER;
        }
    }

    /**
     * 重写JPanel类的paint()方法 g：画笔
     */
    public void paint(Graphics g) {
        //this.getImage().paintIcon(null,g,this.x,this.y);
        Images.sea.paintIcon(null, g, 0, 0);//画海洋图 ----- 不要求掌握
        bs.paintImage(g);
        for (int i = 0; i < sb.length; i++) {//遍历潜艇数组
            sb[i].paintImage(g);//画潜艇
        }
        for (int i = 0; i < mines.length; i++) {//遍历水雷数组
            mines[i].paintImage(g);//画水雷
        }
        for (int i = 0; i < bombs.length; i++) {//遍历炸弹数组
            bombs[i].paintImage(g);//画炸弹
        }
        for (int i = 0; i < smines.length; i++) {
            smines[i].paintImage(g);
        }
        for (int i = 0; i < DA.length; i++) {
            DA[i].paintImage(g);
        }
        for (int i = 0; i < asp.length; i++) {
            asp[i].paintImage(g);
        }
        for (int i = 0; i < am.length; i++) {
            am[i].paintImage(g);
        }
        for (int i = 0; i < ai.length; i++) {
            ai[i].paintImage(g);
        }
        for (int i = 0; i < ai1.length; i++) {
            ai1[i].paintImage(g);
        }
        for (int i = 0; i < ai2.length; i++) {
            ai2[i].paintImage(g);
        }

        g.drawString("SCORE:" + score, 450, 41);
        g.drawString("LIFE:" + bs.life, 450, 61);
        g.drawString("SURPPORT [S]: " + usage, 150, 61);
        g.drawString("TIMESTOP [A]: " + clearbomb, 150, 41);

        if (gameovercheck()) {
            Images.gameover.paintIcon(null, g, 0, 0);
        }
        if (score >= 5000) {
            Images.win.paintIcon(null, g, 0, 0);
        }
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame();//第三步
        World world = new World();
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH + 16, HEIGHT + 39);//宽+16，高+39 得记
        frame.setLocationRelativeTo(null);
        frame.setResizable(true);
        frame.setVisible(true);

        world.Action();
    }
}
















